package com.briup.impl;

import com.briup.impl.constant.ConfigConstant;
import com.briup.inter.Configuration;
import com.briup.inter.client.Client;
import com.briup.inter.client.Gather;
import com.briup.inter.server.DBStore;
import com.briup.inter.server.Server;
import com.briup.inter.support.ConfigurationAware;
import com.briup.inter.support.PropertiesAware;
import com.briup.inter.util.Backup;
import com.briup.inter.util.Log;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class ConfigurationImpl implements Configuration {
    private static ConfigurationImpl configuration = new ConfigurationImpl();

    private ConfigurationImpl() {
    }

    public static ConfigurationImpl getInstance() {
        return configuration;
    }

    // 存对象
    private static Map<String, Object> map = new HashMap<String, Object>();
    // 存属性
    private static Properties properties = new Properties();

    static {
        try {
            parse();
            // 所有的对象 map 初始化
            map.values().forEach(o -> {
                // 对象是不是需要注入 (是不是实现了ConfigurationAware接口)
                try {
                    if (o instanceof ConfigurationAware) {
                        ((ConfigurationAware) o).setConfiguration(configuration);
                    }
                    if(o instanceof PropertiesAware) {
                        ((PropertiesAware)o).init(properties);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 解析文件内容 自动解析
    public static void parse() throws Exception {
        // 1.dom4j对象
        SAXReader reader = new SAXReader();
        // 2.conf.xml -> Document对象
        InputStream in = ConfigurationImpl.class.getClassLoader().getResourceAsStream("conf.xml");
        Document document = reader.read(in);
        // 3.根标签
        Element root = document.getRootElement();
        // 4.子标签
        root.elements().forEach(o -> {
            try {
                // 将来Map<对象名字,对象值> TODO
//            System.out.println(o.getName() + "=" + o.attribute("class").getValue());
                String aClass = o.attribute("class").getValue();
                map.put(o.getName(), Class.forName(aClass).newInstance());
                // 对象o的属性标签
                o.elements().forEach(p -> {
                    // 标签名字 和 标签内容
                    // Map<属性名称,属性值>
//                    System.out.println(p.getName() + "=" + p.getText());
                    properties.put(p.getName(), p.getText());
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
//        properties.forEach((k,v)->{
//            System.out.println(k+"="+v);
//        });

    }

    @Override
    public Log getLogger() throws Exception {
        // 枚举对象
        return (Log) map.get(ConfigConstant.LOGGER);
    }

    @Override
    public Server getServer() throws Exception {
        return (Server) map.get("server");
    }

    @Override
    public Client getClient() throws Exception {
        return (Client) map.get("client");
    }

    @Override
    public DBStore getDbStore() throws Exception {
        return (DBStore) map.get("dbStore");
    }

    @Override
    public Gather getGather() throws Exception {
        return (Gather) map.get("gather");
    }

    @Override
    public Backup getBackup() throws Exception {
        return (Backup) map.get("backup");
    }
}
